﻿#include "Regulation.h"
#include <QMessageBox>
#include <QString>

/************************************************************
*类名：Regulation
*功能：中缀表达式合法性的判断
*作者：韦锴祖
*日期：2018年12月10号
************************************************************/

/**
 * 功能：对输入的中缀表达式进行合法性的判断
 * 参数：dot 小数点的个数
 *      leftBracket 左括号个数
 *      rightBracket 右括号个数
 * 作者：韦锴祖
 * 日期：2018-12-8
 */
bool Regulation::IsRegulation(const QString& str)
{
    int dot = 0;                          //定义并初始化小数点的个数
    int leftBracket = 0;                  //定义并初始化左括号个数
    int rightBracket = 0;                 //定义并初始化右括号个数

    //判断输入的字符串末尾是否有+ - * /号，有则报错
    if(str.endsWith("+") || str.endsWith("-") || str.endsWith("*") || str.endsWith("/")
        || str.endsWith(".") || str.endsWith("%") || str.endsWith("^"))
    {
        QMessageBox::warning(this,tr("错误！"),tr("不能以运算符结尾！"));
        return false;
    }
    else
    {
        if(str.at(0) == '(')
        {
            leftBracket++;
        }
    }

    for(int i = 1; i < str.length(); i++)  //遍历整个QString
    {
        switch(str.at(i).toLatin1())
        {
            //当前字符为"("时，上一字符不能是小数点、右括号、数字、
            case '(':
                dot = 0;
                if(str.at(i-1) ==  '.' || str.at(i-1) ==  ')' || (str.at(i-1) <= '9' && str.at(i-1) >= '0'))
                {
                    QMessageBox::warning(this,tr("错误！"),tr("左括号的左边不能为小数点、右括号、数字，请检查！"));
                    return false;
                }
                leftBracket++;
                break;

            //当前字符为)时，上一字符必须是数字、右括号或者阶乘
            case ')':
                dot = 0;
                if(!((str.at(i-1) <= '9' && str.at(i-1) >= '0') || str.at(i-1) ==  ')' || str.at(i-1) ==  '!'))
                {
                    QMessageBox::warning(this,tr("错误！"),tr("右括号的左边只能是数字、右括号或者阶乘！"));
                    return false;
                }
                rightBracket++;
                break;

            //当前字符为+*/%^时，上一字符只能为数字、右括号或者阶乘
            case '+':
            case '*':
            case '^':
                dot = 0;
                if(!((str.at(i-1) <= '9' && str.at(i-1) >= '0') || str.at(i-1) ==  ')' || str.at(i-1) ==  '!'))
                {
                    QMessageBox::warning(this,tr("错误！"),tr(" +-*/^% 的左边只能是数字、右括号或者阶乘！"));
                    return false;
                }
                break;

            case '/':
                dot = 0;
                if(!((str.at(i-1) <= '9' && str.at(i-1) >= '0') || str.at(i-1) ==  ')' || str.at(i-1) ==  '!'))
                {
                    QMessageBox::warning(this,tr("错误！"),tr(" +-*/^% 的左边只能是数字、右括号或者阶乘！"));
                    return false;
                }
                else if(str.at(i+1) != NULL && str.at(i+1) == '0')
                {
                    QMessageBox::warning(this,tr("错误！"),tr(" '0' 不能作为除数！"));
                    return false;
                }
                break;

            case '%':
                dot = 0;
                if(!((str.at(i-1) <= '9' && str.at(i-1) >= '0') || str.at(i-1) ==  ')' || str.at(i-1) ==  '!'))
                {
                    QMessageBox::warning(this,tr("错误！"),tr(" +-*/^% 的左边只能是数字、右括号或者阶乘！"));
                    return false;
                }
                else if(str.at(i+1) != NULL && str.at(i+1) == '0')
                {
                    QMessageBox::warning(this,tr("错误！"),tr(" '0' 不能作为取余数！"));
                    return false;
                }
                break;

            //当前字符为-时，上一字符只能为数字、括号或者阶乘
            case '-':
                dot = 0;
                if(!((str.at(i-1) <= '9' && str.at(i-1) >= '0') || str.at(i-1) ==  ')' || str.at(i-1) ==  '!'|| str.at(i-1) ==  '('))
                {
                    QMessageBox::warning(this,tr("错误！"),tr(" +-*/ 的左边只能是数字或者右括号！"));
                    return false;
                }
                break;

            //当前字符为阶乘时，上一字符必须为数字或者右括号
            case '!':
                dot = 0;
                if(!((str.at(i-1) <= '9' && str.at(i-1) >= '0') || str.at(i-1) == ')'))
                {
                    QMessageBox::warning(this,tr("错误！"),tr("'!'的左边必须是数字或者右括号！"));
                    return false;
                }
                break;

            //当前字符为小数点时，上一字符必须为数字
            case '.':
                dot++;
                if(!(str.at(i-1) <= '9' && str.at(i-1) >= '0'))
                {
                    QMessageBox::warning(this,tr("错误！"),tr("小数点的左边必须是数字！"));
                    return false;
                }
                else if(dot > 1)
                {
                    QMessageBox::warning(this,tr("错误！"),tr("一串数字不能有多个小数点！"));
                    return false;
                }
                break;

            //当前字符为数字时，上一字符不能为右括号
            default:
                if(str.at(i-1) == ')')
                {
                    QMessageBox::warning(this,tr("错误！"),tr("数字的左边不能是又括号！"));
                    return false;
                }
                break;
        }

    }

    //左右括号数目不相等
    if(leftBracket != rightBracket)
    {
        QMessageBox::warning(this,tr("错误！"),tr("左右括号数不相等！"));
        return false;
    }
    return true;
}

